/**
 *   _                                                          _   
 *  | | ____ _ _ __ _ __ ___   __ _  ___           _ __ ___ ___| |_ 
 *  | |/ / _` | '__| '_ ` _ \ / _` |/ __|  _____  | '__/ _ | __| __|
 *  |   < (_| | |  | | | | | | (_| | (__  |_____| | | |  __|__ \ |_ 
 *  |_|\_\__,_|_|  |_| |_| |_|\__,_|\___|         |_|  \___|___/\__|
 *         
 *  Copyright  2011 Kondra, Inc. 
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.kondra.karmac.rest
{
   import flash.display.Loader;
   import flash.events.Event;
   import flash.events.IOErrorEvent;
   import flash.events.ProgressEvent;
   import flash.net.URLRequest;

   /**
    * <code>ISericeTask</code> implementation to load media content (such as images or 
    * swf movies) from services. This implementation uses the <code>Loader</code> class
    * to load media content from a service.
    * 
    * @see Loader
    * 
    * @author Jared Kaplan
    */ 
   public class MediaServiceTask extends AbstractServiceTask
   {
      private var m_request:URLRequest;
      private var m_loader:Loader;
      
      public function MediaServiceTask( request:URLRequest, serviceEndpoint:IServiceEndpoint = null  ) 
      {
         super( serviceEndpoint );
         
         m_request = request;
      }
      
      //
      // AbstractServiceTask implementation
      //
      
      /**
       * @inheritDoc
       */ 
      protected override function handleInitializeTask() : void 
      {
         m_loader = new Loader();
         
         if( isCompleteHandlerSet() )
            m_loader.contentLoaderInfo.addEventListener( Event.COMPLETE, handleLoaderComplete );
         
         if( isErrorHandlerSet() )
            m_loader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, handleLoaderError )
         
         if( isProgressHandlerSet() )
            m_loader.contentLoaderInfo.addEventListener( ProgressEvent.PROGRESS, handleLoaderProgress );
      }
      
      /**
       * @inheritDoc
       */ 
      protected override function handleInvokeTask() : void {
         m_loader.load( m_request );
      }
      
      /**
       * @inheritDoc
       */ 
      protected override function handleCancelTask() : void
      {
         try
         {
            m_loader.close();
         }
         catch( ex:Error ) {
         }
      }
      
      /**
       * @inheritDoc
       */ 
      public override function isComplete() : Boolean {
         return m_loader.contentLoaderInfo.bytesLoaded == m_loader.contentLoaderInfo.bytesTotal;
      }

      /**
       * @inheritDoc
       */ 
      public override function getSize() : int { 
         return m_loader != null && m_loader.contentLoaderInfo != null ? m_loader.contentLoaderInfo.bytesTotal : 0; 
      }
      
      /**
       * @inheritDoc
       */ 
      public override function getUrl() : String { 
         return m_request != null ? m_request.url : null; 
      }
      
      //
      // Loader event handlers
      //
      
      /**
       * Called when the <code>Loader</code> object has finished loading
       * all of the data being requested. This method calls the inherited
       * method <code>handleRequestComplete()</code> to notify all of the
       * service notification handlers that the request is complete.
       * 
       * @see handleRequestComplete
       */ 
      private function handleLoaderComplete( event:Event ) : void {
         handleRequestComplete( event.target.content, this, event );
      }
      
      /**
       * Called when the <code>Loader</code> fires an error event while
       * the data is being requested. This method calls the inherited
       * method <code>handleRequestError()</code> to notify all of the
       * service notification handlers that there has been an error.
       * 
       * @see handleRequestError
       */ 
      private function handleLoaderError( event:IOErrorEvent ) : void {
         handleRequestError( null, this, event, [event.text] );
      }
      
      /**
       * Called while the <code>Loader</code> is loading data to report
       * progress. This method calls the inherited method <code>handleRequestProgress()</code>
       * to notify all of the service notification handlers that there has been an error.
       * 
       * @see handleRequestProgress
       */ 
      private function handleLoaderProgress( event:ProgressEvent ) : void {
         handleRequestProgress( event.bytesLoaded, this, event );
      }
   }
}